package com.yugao.fintech.antelope.infra.file.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yugao.fintech.antelope.infra.file.assembly.MaterialAssembly;
import com.yugao.fintech.antelope.infra.file.mapper.MaterialMapper;
import com.yugao.fintech.antelope.infra.file.service.MediaMaterialService;
import com.yugao.fintech.antelope.infra.group.service.DataGroupService;
import com.yugao.fintech.antelope.infra.module.file.constants.MaterialTypeEnum;
import com.yugao.fintech.antelope.infra.module.file.model.entity.MediaMaterial;
import com.yugao.fintech.antelope.infra.module.file.model.rqrs.MediaMaterialPageReq;
import com.yugao.fintech.antelope.infra.module.file.model.rqrs.MediaMaterialResp;
import com.yugao.fintech.antelope.infra.module.file.model.rqrs.MediaMaterialSaveReq;
import com.yugao.fintech.antelope.infra.module.file.model.rqrs.MediaMaterialUpdateReq;
import com.yugao.fintech.antelope.infra.module.group.model.entity.DataGroup;
import com.yugao.fintech.antelope.infra.module.group.model.rqrs.DataGroupDeleteReq;
import com.yugao.fintech.antelope.infra.module.group.model.rqrs.DataGroupListReq;
import com.yugao.fintech.antelope.infra.module.group.model.rqrs.DataGroupResp;
import com.yugao.fintech.antelope.base.model.constants.CommonCons;
import com.yugao.fintech.antelope.base.model.enums.DataGroupBizTypeEnum;
import com.yugao.fintech.framework.assistant.utils.StringUtils;
import com.yugao.fintech.framework.assistant.utils.exception.BizException;
import com.yugao.fintech.framework.mybatisplus.utils.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 素材
 *

 */
@Slf4j
@Service
public class MediaMaterialServiceImpl extends ServiceImpl<MaterialMapper, MediaMaterial>
    implements IService<MediaMaterial>, MediaMaterialService {
    @Autowired
    private MaterialAssembly materialAssembly;
    @Autowired
    private DataGroupService dataGroupService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteGroup(DataGroupDeleteReq req) {
        DataGroup firstGroup = dataGroupService.listByIds(req.getIds()).stream().findFirst()
                .orElseThrow(() -> new BizException("删除的数据不存在"));

        DataGroupListReq listReq = new DataGroupListReq();
        listReq.setBizType(DataGroupBizTypeEnum.MATERIAL.getType())
                .setGroupType(firstGroup.getGroupType())
                .setCode(CommonCons.DataGroup.DEFAULT_CODE);
        DataGroupResp defaultGroup = dataGroupService.listGroup(listReq).stream().findFirst()
                .orElseThrow(() -> new BizException("未查询到默认分组, 请联系管理员"));

        // 将被删除的组下面数据移动到默认分组下
        this.update(MediaMaterial.luw().set(MediaMaterial::getGroupId, defaultGroup.getId()).in(MediaMaterial::getGroupId, req.getIds()));
        return dataGroupService.deleteGroup(req);
    }

    @Override
    public IPage<MediaMaterialResp> pageMaterial(MediaMaterialPageReq req) {
        Set<Long> groupIds = new HashSet<>();
        groupIds.add(req.getGroupId());

        // 查询分组树的子节点
        List<DataGroupResp> groupList = dataGroupService.listChildrenGroup(req.getGroupId());
        groupIds.addAll(groupList.stream().map(DataGroupResp::getId).collect(Collectors.toList()));

        LocalDateTime beginTime = req.getBeginLocalDateTime();
        LocalDateTime endTime = req.getEndLocalDateTime();
        LambdaQueryWrapper<MediaMaterial> lqw = MediaMaterial.lqw()
            .eq(StringUtils.isNotEmpty(req.getType()), MediaMaterial::getType, req.getType())
            .in(MediaMaterial::getGroupId, groupIds)
            .like(StringUtils.isNotEmpty(req.getName()), MediaMaterial::getName, req.getName())
            .ge(Objects.nonNull(beginTime), MediaMaterial::getCreatedAt, beginTime)
            .le(Objects.nonNull(endTime), MediaMaterial::getCreatedAt, endTime)
            .orderByDesc(MediaMaterial::getCreatedAt);
        IPage<MediaMaterial> pageData = this.page(PageUtil.to(req), lqw);
        return PageUtil.to(pageData, materialAssembly::toMaterialResp);
    }

    @Override
    public List<MediaMaterialResp> listMaterial(List<Long> ids) {
        return this.listByIds(ids).stream().map(materialAssembly::toMaterialResp).collect(Collectors.toList());
    }

    @Override
    public MediaMaterialResp getMaterial(Long id) {
        MediaMaterial entity = this.getById(id);
    	return materialAssembly.toMaterialResp(entity);
    }

    @Override
    public boolean saveMaterial(MediaMaterialSaveReq req) {
        MaterialTypeEnum.checkExist(req.getType());
        MediaMaterial entity = materialAssembly.toMaterial(req);
    	return this.save(entity);
    }

    @Override
    public boolean updateMaterial(MediaMaterialUpdateReq req) {
        MediaMaterial entity = materialAssembly.toMaterial(req);
    	return this.updateById(entity);
    }

    @Override
    public boolean deleteMaterial(Long id) {
    	return this.removeById(id);
    }
    
    @Override
    public boolean batchDeleteMaterial(List<Long> ids) {
    	return this.removeByIds(ids);
    }
}
